package com.pokeoffice.client;

import java.awt.Image;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Vector;

import javax.swing.ImageIcon;

import com.pokeoffice.interfaces.Command;
import com.pokeoffice.logs.Log;

/**
 * The Class Client.
 */
public class Client extends Thread {

	/** The PORT. */
	private final int PORT = 2340;
	
	/** The HOST. */
	private final String HOST = "localhost";
	
	/** The Constant WIDTH. */
	public static final int WIDTH = 800;

	/** The Constant HEIGHT. */
	public static final int HEIGHT = 600;
	
	/** The welcome. */
	public static Image welcome = new ImageIcon("images/welcome.png").getImage();
	
	/** The back. */
	public static Image back = new ImageIcon("images/back.png").getImage();
	
	/** The oak. */
	public static Image oak = new ImageIcon("images/oak.png").getImage();

	/** The socket. */
	private Socket socket = null;
	
	/** The out. */
	private ObjectOutputStream out = null;

	/** The shutdown. */
	private volatile boolean shutdown = false;
	
	/** The debug. */
	private boolean debug = false;

	/** The commands. */
	private List<Command> commands = null;

	/** The session. */
	private Session session = null;
	
	/** The session thread. */
	private Thread sessionThread = null;

	/**
	 * Instantiates a new client.
	 */
	public Client() {
		Log.write(Log.SERV, "CREATING CLIENT");

		try {
			Log.write(Log.SERV, this + "Connecting to " + HOST + " on port "
					+ PORT);
			socket = new Socket(HOST, PORT);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		try {
			Log.write(Log.SERV, this + "Getting input and output streams");
			out = new ObjectOutputStream(socket.getOutputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}

		shutdown = false;
		commands = new Vector<Command>();

		session = new Session(this);
		sessionThread = new Thread(session);
	}

	/**
	 * Put.
	 *
	 * @param com the com
	 */
	public synchronized void put(Command com) {
		if (debug) {
			Log.write(Log.SERV, this + "Command Added");
		}

		commands.add(com);
		notifyAll();
	}

	/* (non-Javadoc)
	 * @see java.lang.Thread#run()
	 */
	public void run() {
		Log.write(Log.SERV, this + "Starting Session");
		sessionThread.start();

		while (!shutdown) {
			synchronized (this) {
				if (!commands.isEmpty()) {
					try {
						if (debug) {
							Log.write(Log.SERV, this + "Writing Command");
						}

						Command com = commands.remove(0);
						out.writeObject(com);
					} catch (IOException e) {
						e.printStackTrace();
					}
				} else {
					try {
						wait();
					} catch (InterruptedException e) {
					}
				}
			}
		}
	}

	/**
	 * Shutdown.
	 */
	public synchronized void shutdown() {
		// FIXME
	}
	
	/**
	 * Update.
	 */
	public synchronized void update() {
		
	}

	/* (non-Javadoc)
	 * @see java.lang.Thread#toString()
	 */
	public String toString() {
		return "Client: ";
	}
}
